package com.resume.aipeople.service.ai.asr;

import com.alibaba.nls.client.AccessToken;
import com.alibaba.nls.client.protocol.InputFormatEnum;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.SampleRateEnum;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriber;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriberListener;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriberResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.ByteArrayInputStream;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * 阿里云语音识别策略实现
 * 基于阿里云智能语音服务 Java SDK
 */
@Component
@Slf4j
public class AliyunSpeechRecognitionStrategy implements SpeechRecognitionStrategy {
    
    @Value("${aliyun.voice.access.key.id:}")
    private String accessKeyId;
    
    @Value("${aliyun.voice.access.key.secret:}")
    private String accessKeySecret;
    
    @Value("${aliyun.voice.app.key:}")
    private String appKey;
    
    @Value("${aliyun.voice.gateway.url:wss://nls-gateway-cn-shanghai.aliyuncs.com/ws/v1}")
    private String gatewayUrl;
    
    private NlsClient nlsClient;
    
    @PostConstruct
    public void init() {
        if (isAvailable()) {
            try {
                // 获取AccessToken
                AccessToken accessToken = new AccessToken(accessKeyId, accessKeySecret);
                accessToken.apply();
                
                // 创建NlsClient实例
                if (gatewayUrl != null && !gatewayUrl.isEmpty()) {
                    nlsClient = new NlsClient(gatewayUrl, accessToken.getToken());
                } else {
                    nlsClient = new NlsClient(accessToken.getToken());
                }
                
                log.info("阿里云语音识别客户端初始化成功");
            } catch (Exception e) {
                log.error("阿里云语音识别客户端初始化失败", e);
                nlsClient = null;
            }
        }
    }
    
    @PreDestroy
    public void destroy() {
        if (nlsClient != null) {
            nlsClient.shutdown();
            log.info("阿里云语音识别客户端已关闭");
        }
    }
    
    @Override
    public String getStrategyName() {
        return "aliyun";
    }
    
    @Override
    public String getDisplayName() {
        return "阿里云语音识别";
    }
    
    @Override
    public boolean isAvailable() {
        return accessKeyId != null && !accessKeyId.isEmpty() &&
               accessKeySecret != null && !accessKeySecret.isEmpty() &&
               appKey != null && !appKey.isEmpty();
    }
    
    @Override
    public Mono<String> speechToText(MultipartFile audioFile) {
        return Mono.fromCallable(() -> {
            if (!isAvailable() || nlsClient == null) {
                log.info("阿里云语音API未配置或初始化失败，使用模拟ASR");
                return mockSpeechToText(audioFile);
            }
            
            try {
                byte[] audioData = audioFile.getBytes();
                String format = detectAudioFormat(audioFile);
                int sampleRate = detectSampleRate(audioData, format);
                
                log.info("阿里云ASR - 音频文件信息: 格式={}, 大小={}KB, 采样率={}", 
                        format, audioData.length/1024, sampleRate);
                
                // 创建识别结果容器
                CompletableFuture<String> resultFuture = new CompletableFuture<>();
                
                // 创建识别监听器
                SpeechTranscriberListener listener = new SpeechTranscriberListener() {
                    private StringBuilder fullText = new StringBuilder();
                    
                    @Override
                    public void onTranscriptionResultChange(SpeechTranscriberResponse response) {
                        // 中间结果
                        if (response.getTransSentenceText() != null) {
                            log.debug("阿里云ASR中间结果: {}", response.getTransSentenceText());
                        }
                    }
                    
                    @Override
                    public void onTranscriberStart(SpeechTranscriberResponse response) {
                        log.info("阿里云ASR开始识别, task_id: {}", response.getTaskId());
                    }
                    
                    @Override
                    public void onSentenceBegin(SpeechTranscriberResponse response) {
                        log.debug("阿里云ASR句子开始");
                    }
                    
                    @Override
                    public void onSentenceEnd(SpeechTranscriberResponse response) {
                        // 识别出一句话
                        if (response.getTransSentenceText() != null && !response.getTransSentenceText().isEmpty()) {
                            fullText.append(response.getTransSentenceText());
                            log.info("阿里云ASR句子结束: {}", response.getTransSentenceText());
                        }
                    }
                    
                    @Override
                    public void onTranscriptionComplete(SpeechTranscriberResponse response) {
                        // 识别完成
                        String result = fullText.toString().trim();
                        log.info("阿里云ASR识别完成: {}", result);
                        resultFuture.complete(result);
                    }
                    
                    @Override
                    public void onFail(SpeechTranscriberResponse response) {
                        // 识别失败
                        String error = "阿里云ASR识别失败: " + response.getStatusText();
                        log.error(error);
                        resultFuture.completeExceptionally(new RuntimeException(error));
                    }
                };
                
                // 创建识别器
                SpeechTranscriber transcriber = new SpeechTranscriber(nlsClient, listener);
                transcriber.setAppKey(appKey);
                
                // 设置音频格式
                if ("pcm".equals(format)) {
                    transcriber.setFormat(InputFormatEnum.PCM);
                } else if ("wav".equals(format)) {
                    transcriber.setFormat(InputFormatEnum.WAV);
                } else {
                    // 默认使用PCM
                    transcriber.setFormat(InputFormatEnum.PCM);
                }
                
                // 设置采样率
                if (sampleRate == 8000) {
                    transcriber.setSampleRate(SampleRateEnum.SAMPLE_RATE_8K);
                } else {
                    transcriber.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
                }
                
                // 设置其他参数
                transcriber.setEnableIntermediateResult(false);  // 不返回中间结果
                transcriber.setEnablePunctuation(true);          // 生成标点符号
                transcriber.setEnableITN(true);                  // 规整化数字
                
                // 可选的高级参数
                // transcriber.addCustomedParam("max_sentence_silence", 800);  // vad断句参数
                // transcriber.addCustomedParam("enable_semantic_sentence_detection", false);  // 语义断句
                
                try {
                    // 开始识别
                    transcriber.start();
                    
                    // 发送音频数据
                    ByteArrayInputStream inputStream = new ByteArrayInputStream(audioData);
                    byte[] buffer = new byte[3200];  // 阿里云推荐的数据包大小
                    int bytesRead;
                    
                    while ((bytesRead = inputStream.read(buffer)) > 0) {
                        transcriber.send(buffer, bytesRead);
                        
                        // 模拟实时发送，阿里云SDK要求
                        int deltaSleep = getSleepDelta(bytesRead, sampleRate);
                        Thread.sleep(deltaSleep);
                    }
                    
                    // 通知识别结束
                    transcriber.stop();
                    
                    // 等待识别结果，最多等待30秒
                    String result = resultFuture.get(30, TimeUnit.SECONDS);
                    
                    if (result != null && !result.trim().isEmpty()) {
                        log.info("阿里云ASR识别成功: {}", result);
                        return result;
                    } else {
                        log.warn("阿里云ASR识别结果为空");
                        return "";
                    }
                    
                } finally {
                    // 关闭识别器
                    if (transcriber != null) {
                        transcriber.close();
                    }
                }
                
            } catch (Exception e) {
                log.error("阿里云语音识别异常", e);
                return mockSpeechToText(audioFile);
            }
        })
        .doOnError(error -> log.error("阿里云语音识别调用失败", error))
        .onErrorReturn(mockSpeechToText(audioFile));
    }
    
    /**
     * 根据数据大小计算sleep时间（阿里云SDK要求）
     */
    private int getSleepDelta(int dataSize, int sampleRate) {
        // 仅支持16位采样，单通道
        int sampleBytes = 16;
        int soundChannel = 1;
        return (dataSize * 10 * 8000) / (160 * sampleRate);
    }
    
    private String mockSpeechToText(MultipartFile audioFile) {
        String filename = audioFile.getOriginalFilename();
        return "这是阿里云模拟的语音识别结果，文件名: " + filename;
    }
}



